package com.lonely.order.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lonely.common.utils.SecurityUtils;
import com.lonely.goods.domain.dto.goods.GoodsMaterialItemDTO;
import com.lonely.goods.domain.dto.goods.GoodsQuotationSheetPartMaterialDTO;
import com.lonely.goods.domain.entity.SysGoodsPartMaterial;
import com.lonely.goods.service.IGoodsPartMaterialService;
import com.lonely.order.domain.entity.SysOrder;
import com.lonely.order.domain.entity.SysOrderPart;
import com.lonely.order.domain.entity.SysOrderPartMaterial;
import com.lonely.order.mapper.SysOrderPartMaterialMapper;
import com.lonely.order.service.IOrderPartMaterialService;
import com.lonely.order.service.IOrderPartService;
import com.lonely.order.service.IOrderService;
import com.lonely.common.utils.JsonUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author : 黄志标
 * @date: 2025/7/30 14:04
 * @description: 订单部件物料服务实现类
 */
@Service
public class OrderPartMaterialServiceImpl extends ServiceImpl<SysOrderPartMaterialMapper, SysOrderPartMaterial> implements IOrderPartMaterialService {

    @Autowired
    private IGoodsPartMaterialService goodsPartMaterialService;

    @Autowired
    private IOrderPartService orderPartService;

    @Autowired
    private IOrderService orderService;

    /**
     * 创建订单物料
     *
     * @param sysOrderPart
     * @param goodsPartId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createOrderPartMaterials(SysOrderPart sysOrderPart, Long goodsPartId) {
        List<SysGoodsPartMaterial> goodsPartMaterials = this.goodsPartMaterialService.list(new LambdaQueryWrapper<SysGoodsPartMaterial>()
                .eq(SysGoodsPartMaterial::getGoodsPartId, goodsPartId)
        );
        if (CollUtil.isEmpty(goodsPartMaterials)) {
            return;
        }

        List<SysOrderPartMaterial> sysOrderPartMaterials = goodsPartMaterials.stream().map(goodsPartMaterial -> {
            SysOrderPartMaterial sysOrderPartMaterial = new SysOrderPartMaterial();
            BeanUtils.copyProperties(goodsPartMaterial, sysOrderPartMaterial);
            sysOrderPartMaterial.setOrderId(sysOrderPart.getOrderId());
            sysOrderPartMaterial.setOrderPartId(sysOrderPart.getId());
            sysOrderPartMaterial.setProduceOrderId(sysOrderPart.getProduceOrderId());
            sysOrderPartMaterial.setSourceGoodsPartId(goodsPartMaterial.getGoodsPartId());
            sysOrderPartMaterial.setSourceGoodsMaterialId(goodsPartMaterial.getId());
            sysOrderPartMaterial.setCreateBy(SecurityUtils.getUserId());
            sysOrderPartMaterial.setUpdateBy(SecurityUtils.getUserId());
            return sysOrderPartMaterial;
        }).collect(Collectors.toList());
        super.saveBatch(sysOrderPartMaterials);
    }

    /**
     * 获取部件id对应的物料信息(全颜色数据，没有配置设置初始值)
     *
     * @param orderPartId
     * @return
     */
    @Override
    public List<GoodsQuotationSheetPartMaterialDTO> queryQuotationSheetPartMaterials(Long orderPartId) {
        // 查询已配置的部件物料信息
        List<GoodsQuotationSheetPartMaterialDTO> existsPartMaterials = this.queryPartMaterials(orderPartId);

        // 根据设置的所有颜色进行适配
        SysOrderPart orderPart = this.orderPartService.getById(orderPartId);
        Assert.notNull(orderPart, "部件信息不存在");

        SysOrder sysOrder = this.orderService.getById(orderPart.getOrderId());
        Assert.notNull(sysOrder, "订单信息不存在");

        if (StrUtil.isBlank(sysOrder.getColor())) {
            // 没有设置颜色
            return new ArrayList<>();
        }

        Map<String, GoodsQuotationSheetPartMaterialDTO> colorMaterialMap = existsPartMaterials.stream().collect(Collectors.toMap(GoodsQuotationSheetPartMaterialDTO::getGoodsColor, Function.identity(), (a, b) -> b));
        List<GoodsQuotationSheetPartMaterialDTO> result = new ArrayList<>();
        if (colorMaterialMap.containsKey(sysOrder.getColor())) {
            result.add(colorMaterialMap.get(sysOrder.getColor()));
        } else {
            // 该颜色没有配置，则初始化数据
            GoodsQuotationSheetPartMaterialDTO sheetPartMaterialDTO = new GoodsQuotationSheetPartMaterialDTO();
            sheetPartMaterialDTO.setGoodsPartId(orderPartId);
            sheetPartMaterialDTO.setGoodsColor(sysOrder.getColor());
            sheetPartMaterialDTO.setMaterials(new ArrayList<>());
            result.add(sheetPartMaterialDTO);
        }
        return result;
    }


    /**
     * 获取部件id对应的物料信息
     *
     * @param orderPartId
     * @return
     */
    private List<GoodsQuotationSheetPartMaterialDTO> queryPartMaterials(Long orderPartId) {
        // 查询部件的所有物料信息
        List<SysOrderPartMaterial> sysOrderPartMaterials = super.list(new LambdaQueryWrapper<SysOrderPartMaterial>()
                .eq(SysOrderPartMaterial::getOrderPartId, orderPartId));
        if (CollUtil.isEmpty(sysOrderPartMaterials)) {
            return new ArrayList<>();
        }

        // 根据颜色和部件分组
        Map<String, List<SysOrderPartMaterial>> partMaterialGroup = sysOrderPartMaterials.stream().collect(Collectors.groupingBy(x -> String.format("%s_%s", x.getOrderPartId(), x.getGoodsColor())));

        List<GoodsQuotationSheetPartMaterialDTO> existsPartMaterials = new ArrayList<>();
        partMaterialGroup.forEach((key, value) -> {
            GoodsQuotationSheetPartMaterialDTO sheetPartMaterialDTO = new GoodsQuotationSheetPartMaterialDTO();
            String[] split = key.split("_");
            sheetPartMaterialDTO.setGoodsPartId(Convert.toLong(split[0]));
            sheetPartMaterialDTO.setGoodsColor(split[1]);

            List<GoodsMaterialItemDTO> goodsMaterialS = value.stream().map(x -> {
                GoodsMaterialItemDTO goodsMaterialItemDTO = new GoodsMaterialItemDTO();
                BeanUtils.copyProperties(x, goodsMaterialItemDTO);
                goodsMaterialItemDTO.setGoodsPartMaterialId(x.getId());
                goodsMaterialItemDTO.setSecondProcess(JsonUtil.parseArray(x.getSecondProcess(), String.class));
                goodsMaterialItemDTO.setSku(x.getMaterialSku());
                goodsMaterialItemDTO.setColor(x.getMaterialColor());
                goodsMaterialItemDTO.setTypeName(x.getMaterialTypeName());
                goodsMaterialItemDTO.setPic(x.getMaterialPic());

                // 计算金额 物料单价 * 单件使用量 * ( 1 + 损耗率/100 ) * ( 1 + 利润率/100 )
                BigDecimal amount = NumberUtil.mul(StrUtil.blankToDefault(x.getUnitPrice(), "0"),
                        StrUtil.blankToDefault(x.getSinglePieceUsage(), "0"),
                        NumberUtil.add(NumberUtil.div(StrUtil.blankToDefault(x.getLoss(), "0"), "100"), new BigDecimal(1)).toPlainString(),
                        NumberUtil.add(NumberUtil.div(StrUtil.blankToDefault(x.getSupplierProfitMargin(), "0"), "100"), new BigDecimal(1)).toPlainString()
                );
                amount = NumberUtil.round(amount, 4);
                goodsMaterialItemDTO.setAmount(amount.toPlainString());
                return goodsMaterialItemDTO;
            }).collect(Collectors.toList());
            sheetPartMaterialDTO.setMaterials(goodsMaterialS);

            existsPartMaterials.add(sheetPartMaterialDTO);
        });

        return existsPartMaterials;
    }
}
